﻿using Common.Communication;
using Common.Device.DeviceDb;
using Common.Device.Enums;
using Common.Device.Interfaces;
using Common.Device.Models;
using HandyControl.Expression.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AnGuiYi.JueYuanNaiYa
{
    internal class EEC7473SerialPort : SerialPortBase, IJueYuanNaiYa
    {
        public string Name { get; set; }
        public EEC7473SerialPort(UseDevice device) :base(device.port, Convert.ToInt32(device.parameter), timeout: 1500)
        {
            Name = device.name;
        }

        public Result<List<JueYuanNaiYaResult>> SetTest(Common.Device.Models.JueYuanNaiYa parameter)
        {
            lock (this)
            {
                var result = new Result<List<JueYuanNaiYaResult>>(new List<JueYuanNaiYaResult>());
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"设置测试参数");
                AppendInfo(Name, $"切换到测试程序1");
                write = WriteThenRead(CmdAcw);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "切换到测试程序1失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"关闭蜂鸣器");
                write = WriteThenRead(CmdAlarmOff);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "关闭蜂鸣器失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                string type = "";
                switch (parameter.mode)
                {
                    case AnGuiYiEnum.TestMode.交流耐压:
                        type = "AC";
                        break;
                    default:
                        result.IsSucceed = false;
                        result.Err = parameter.mode.ToString() + "暂不支持";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                }
                if (parameter.mode == AnGuiYiEnum.TestMode.交流耐压)
                {
                    AppendInfo(Name, $"设置频率{parameter.电压频率}Hz");
                    write = WriteThenRead(CmdFreq(parameter.电压频率 == 50 ? 0 : 1));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置频率失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(200);
                    read = WriteThenRead(CmdGetFreq);
                    if (!read.IsSucceed || !int.TryParse(read.Value.Trim(), out int va) || va != (parameter.电压频率 == 50 ? 0 : 1))
                    {
                        result.IsSucceed = false;
                        result.Err = "设置频率失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                }
                if (parameter.mode == AnGuiYiEnum.TestMode.交流耐压|| parameter.mode == AnGuiYiEnum.TestMode.直流耐压)
                {
                    AppendInfo(Name, $"设置电弧{parameter.电弧值}");
                    if (parameter.电弧值 != 0)
                    {
                        write = WriteThenRead(CmdArc(parameter.电弧值));
                        if (!write.IsSucceed)
                        {
                            result.IsSucceed = false;
                            result.Err = "设置电弧失败";
                            AppendTip(Name, result.Err);
                            return result.EndTime();
                        }
                        Thread.Sleep(100);
                        read = WriteThenRead(CmdGetArc);
                        if (!read.IsSucceed || !double.TryParse(read.Value, out double arc) || arc != parameter.电弧值)
                        {
                            result.IsSucceed = false;
                            result.Err = "设置电弧失败";
                            AppendTip(Name, result.Err);
                            return result.EndTime();
                        }
                    }
                    write = WriteThenRead(CmdArcState(parameter.电弧值 > 0 ? 1 : 0));
                    if (!write.IsSucceed)
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电弧失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    Thread.Sleep(100);
                    read = WriteThenRead(CmdGetArcState);
                    if (!read.IsSucceed || !double.TryParse(read.Value, out double state) || state != (parameter.电弧值 > 0 ? 1 : 0))
                    {
                        result.IsSucceed = false;
                        result.Err = "设置电弧失败";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                }
                AppendInfo(Name, $"设置电压{parameter.电压值}kV");
                write = WriteThenRead(CmdSetVol(parameter.电压值));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetVol);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double v) || v != parameter.电压值)
                {
                    result.IsSucceed = false;
                    result.Err = "设置电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置时间单位s");
                write = WriteThenRead(CmdTimeUnit);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置时间单位s失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                //Thread.Sleep(200);
                //read = WriteThenRead(CmdGetTimeUnit);
                //if (!read.IsSucceed || !read.Value.Contains("s"))
                //{
                //    result.IsSucceed = false;
                //    result.Err = "设置时间单位s失败";
                //    AppendTip(Name, result.Err);
                //    return result.EndTime();
                //}
                AppendInfo(Name, $"设置上升时间{parameter.上升时间}s");
                write = WriteThenRead(CmdUpTime(parameter.上升时间));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上升时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetUpTime);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double ut) || ut != parameter.上升时间)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上升时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置保持时间{parameter.测试时间}s");
                write = WriteThenRead(CmdKeepTime(parameter.测试时间));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置保持时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetKeepTime);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double kt) || kt != parameter.测试时间)
                {
                    result.IsSucceed = false;
                    result.Err = "设置保持时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置下降时间{parameter.下降时间}s");
                write = WriteThenRead(CmdDownTime(parameter.下降时间));
                if (!read.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下降时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetDownTime);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double dt) || dt != parameter.下降时间)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下降时间失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置上限{parameter.上限值}");
                write = WriteThenRead(CmdMax(parameter.上限值 ?? 0.0));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetMax);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double ma) || ma != parameter.上限值)
                {
                    result.IsSucceed = false;
                    result.Err = "设置上限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置下限{parameter.下限值}");
                write = WriteThenRead(CmdMin(parameter.下限值 ?? 0.0));
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(200);
                read = WriteThenRead(CmdGetMin);
                if (!read.IsSucceed || !double.TryParse(read.Value, out double mi) || mi != parameter.下限值)
                {
                    result.IsSucceed = false;
                    result.Err = "设置下限失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"设置测试参数成功");
                AppendInfo(Name, $"开始测试");
                write = WriteThenRead(CmdStart);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "开始测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                string dvalue = "";
                DateTime testTime = DateTime.Now.AddSeconds(parameter.上升时间 + parameter.测试时间 + parameter.下降时间 + 3);
                while (DateTime.Now < testTime)
                {
                    Thread.Sleep(500);
                    if (Common.Device.DeviceService.IsStop)
                    {
                        result.IsSucceed = false;
                        result.Err = "停止测试";
                        AppendTip(Name, result.Err);
                        return result.EndTime();
                    }
                    read = WriteThenRead(CmdFetch, wait: 200);
                    if (read.IsSucceed && read.Value.Contains("Dwell"))
                    {
                        dvalue = read.Value;
                    }
                    if (read.IsSucceed && read.Value.StartsWith("M1") && (read.Value.Contains("LO") || read.Value.Contains("HI") || read.Value.Contains("Pass")))
                    {
                        break;
                    }
                }
                read = WriteThenRead(CmdFetch, wait: 200);
                if (!read.IsSucceed || !read.Value.StartsWith("M1") || read.Value.Count(o => o == ',') != 6)
                {
                    WriteThenRead(CmdStop);
                    result.IsSucceed = false;
                    result.Err = "测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                WriteThenRead(CmdStop);
                //解析测试结果 M1,ACW,Pass,0.01,0.000,5.0,1
                var value = read.Value.Contains("Pass") == false ?
                    read.Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    : dvalue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                JueYuanNaiYaResult jueYuanNai = new JueYuanNaiYaResult()
                {
                    type = value[1],
                    value = value[3] + "kV," + value[4] + "mA",
                    isPass = read.Value.Contains("Pass"),
                };
                AppendResult(Name, jueYuanNai.type + "," + jueYuanNai.value + "," + jueYuanNai.isPass);
                result.Value.Add(jueYuanNai);
                result.IsSucceed = result.Value.Count(o => o.isPass == false) == 0;
                if (!result.IsSucceed)
                    result.Err = "测试未通过";
                return result.EndTime();
            }
        }

        public Result<bool> StopTest()
        {
            lock (this)
            {
                var result = new Result<bool>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"停止测试");
                write = WriteThenRead(CmdStop);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "停止测试失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"停止测试成功");
                return result.EndTime();
            }
        }
        string CmdAlarmOff => "SAL 0\n";
        string CmdAcw => $"FL 1\n";
        string CmdFreq(int freq) { return "EF " + freq + "\n"; }
        string CmdGetFreq => "EF?\n";
        string CmdArc(double arc) => $"EA {arc}\n";
        string CmdGetArc => "EA?\n";
        string CmdArcState(int on) => $"EAD {on}\n";
        string CmdGetArcState => "EAD?\n";
        string CmdSetVol(double vol) { return "EV " + vol  + "\n"; }
        string CmdGetVol => "EV?\n";
        string CmdTimeUnit => "ERWU 0\n";
        string CmdGetTimeUnit => "ERWU?\n";
        string CmdUpTime(double time) { return "ERU " + time + "\n"; }
        string CmdGetUpTime => "ERU?\n";
        string CmdKeepTime(double time) { return "EDW " + time + "\n"; }
        string CmdGetKeepTime => "EDW?\n";
        string CmdDownTime(double time) { return "ERD " + time + "\n"; }
        string CmdGetDownTime => "ERD?\n";
        string CmdMin(double min) { return "EL " + min + "\n"; }
        string CmdGetMin => "EL?\n";
        string CmdMax(double max) { return "EH " + max  + "\n"; }
        string CmdGetMax => "EH?\n";
        string CmdStart => "TEST\n";
        string CmdStop => "RESET\n";
        string CmdFetch => "TD?\n";
    }
}
